package modules.march
{
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.Loader;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.KeyboardEvent;
	import flash.events.MouseEvent;
	import flash.filesystem.File;
	import flash.filesystem.FileMode;
	import flash.filesystem.FileStream;
	import flash.net.FileFilter;
	import flash.net.URLRequest;
	import flash.sampler.NewObjectSample;
	import flash.ui.Keyboard;
	import flash.utils.ByteArray;
	import modules.march.vo.ProjectVO;
	import ui.MapBoardUI;
	import util.Tools;
	
	/**
	 * ...
	 * @author WLDragon 2013-12-12
	 */
	public class MapBoard extends MapBoardUI
	{
		
		public function MapBoard()
		{
			mLoader = new Loader;
			mLoader.alpha = .5;
			mLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoadImageComplete);
			
			mBlockPanel = new Sprite;
			
			mContainer = new Sprite;
			mContainer.addEventListener(MouseEvent.RIGHT_MOUSE_DOWN, onRightDown);
			mContainer.addEventListener(MouseEvent.RIGHT_MOUSE_UP, onRightUp);
			
			mContainer.addChild(mLoader);
			mContainer.addChild(mBlockPanel);
			addChild(mContainer);
			
			//为了分层所以在此处才添加父类的初始化方法添加monr控件
			super();
			
			mSelectView = new TextureSelectPanel;
			mSelectView.x = 200;
			mSelectView.y = 200;
			mSelectView.setTextures(setTexture);
			addChild(mSelectView);
			
			mNewPanel = new NewProject(handleRefer, handleOk, handleCancel);
			
			mFileStream = new FileStream;
			mFile = new File();
			mFile.addEventListener(Event.SELECT, onFileSelect);
			mFile.addEventListener(Event.COMPLETE, onFileComplete);
			
			var str:String = "";
			str += "1、新建，新建指定大小的空白文件或选择参考地图(jpg)新建由参考地图确定大小的文件\n";
			str += "2、打开，选择xx.b的工程文件还原地图进行编辑\n";
			str += "3、保存，把数据保存为xx.d和xx.b两个文件，d用于寻路，b用于在项目中创建地图或还原地图编辑工程\n";
			str += "4、数字键，显示当前选择的数字，两位表示一个纹理的编号，如果有被选中的方块，则该方块的纹理会被些编号的纹理替换\n";
			str += "5、模式，有“普通”和“覆盖”模式，使用空格键切换。覆盖模式中鼠标经过的方块纹理会被选中方块的纹理替换\n";
			str += "6、跟随，勾选跟随后纹理集面板会一直在被选中方块的右下角位置\n";
			str += "7、按住鼠标右键可以拖动地图面板和纹理集面板。\n";
			str += "8、ASDW键可以选中当前方块附近的方块\n";
			str += "9、Ctrl+ASDW可以移动网格，调整其在参考地图上的位置\n";
			str += "10、鼠标点击纹理集面板的纹理，可把选中方块的纹理替换为点击的纹理\n";
			str += "11、X键清除当前选中方块的纹理\n";
			str += "12、鼠标滚轮可以上下移动地图面板";
			labHelp.toolTip = str;
			
			addEventListener(MouseEvent.CLICK, onClick);
			
			//监听键盘
			App.stage.addEventListener(MouseEvent.MOUSE_WHEEL, onWheel);
		}
		
		private function onFileComplete(e:Event):void
		{
			try
			{
				var b:ByteArray = e.target.data as ByteArray;
				b.position = 0;
				//解析文件
				var tx:int = b.readInt(); //纹理方块面板偏移的坐标
				var ty:int = b.readInt();
				var r:int = b.readByte(); //行
				var c:int = b.readByte(); //列
				var w:int = b.readByte(); //纹理块的宽
				var h:int = b.readByte(); //纹理块的高
				
				var n:String = mFile.name.split('.')[0];
				var d:String = mFile.parent.parent.url + "/";
				//加载参考地图
				var url:String = mFile.parent.parent.url + "/maps/" + n + ".jpg";
				var f:File = new File(url);
				var err:String = "";
				if (f.exists)
				{
					if (isLoading == false)
					{
						mLoader.unload();
						mLoader.load(new URLRequest(url));
						isLoading = true;
					}
				}
				else
				{
					err = "<font color='#ff0000'>(找不到:" + url + ")</font>";
				}
				
				f = null;
				
				mBlockPanel.x = tx;
				mBlockPanel.y = ty;
				
				mCurProject = new ProjectVO(n, r, c, w, h, d);
				createBlankMap(err);
				createMap(b);
			}
			catch (error:Error)
			{
				labName.text = "<font color='#ff0000'>请不要把b文件放到C、D、E...等根目录下，使用二级目录</font>";
			}
		}
		
		private function onWheel(e:MouseEvent):void
		{
			if (e.delta > 0)
				mContainer.y += 30;
			else
				mContainer.y -= 30;
		}
		
		private function onKeyDown(e:KeyboardEvent):void
		{
			var c:int = e.keyCode;
			//按的是数字键48~57 96~105
			if (47 < c && c < 58 || 95 < c && c < 106)
			{
				var n:int = c > 95 ? c - 96 : c - 48;
				
				if (isSecond)
				{
					n = n + mFirstNumber * 10;
					mCurBlock.setTexture(n);
					labName.text = mCurProject.name;
					labKeys.text = n.toString();
					isSecond = false;
				}
				else
				{
					mFirstNumber = n;
					labKeys.text = n.toString();
					isSecond = true;
				}
				
				return;
			}
			
			if (Keyboard.X == c)
			{
				//清除纹理
				mCurBlock.setTexture(0);
			}
			else if (Keyboard.A == c || Keyboard.LEFT == c)
			{
				//左
				if (e.ctrlKey)
					mBlockPanel.x--;
				else
					selectNextBlock(1);
			}
			else if (Keyboard.S == c || Keyboard.DOWN == c)
			{
				//下
				if (e.ctrlKey)
					mBlockPanel.y++;
				else
					selectNextBlock(4);
			}
			else if (Keyboard.D == c || Keyboard.RIGHT == c)
			{
				//右
				if (e.ctrlKey)
					mBlockPanel.x++;
				else
					selectNextBlock(3);
			}
			else if (Keyboard.W == c || Keyboard.UP == c)
			{
				//上
				if (e.ctrlKey)
					mBlockPanel.y--;
				else
					selectNextBlock(2);
			}
			else if (Keyboard.SPACE == c)
			{
				isCover = !isCover;
				labModel.text = isCover ? "覆盖模式" : "普通模式";
			}
		}
		
		/**
		 * 选择下一个方块
		 * @param	$dir 方向（1左 2上 3右 4下）
		 */
		private function selectNextBlock($dir:int):void
		{
			var n:int;
			var i:int = mBlockPanel.getChildIndex(mCurBlock);
			switch ($dir)
			{
				case 1: 
					n = i - 1;
					break;
				case 2: 
					n = i - mColumn;
					break;
				case 3: 
					n = i + 1;
					break;
				case 4: 
					n = i + mColumn;
					break;
				default: 
			}
			
			if (n >= 0 && n < mBlockPanel.numChildren)
			{
				mCurBlock.changeState(false);
				mCurBlock = mBlockPanel.getChildAt(n) as Block;
				mCurBlock.changeState(true);
				if (chkFollow.selected)
				{
					mSelectView.x = mContainer.x + mBlockPanel.x + mCurBlock.x + 32;
					mSelectView.y = mContainer.y + mBlockPanel.y + mCurBlock.y + 32;
				}
			}
		}
		
		private function onRightUp(e:MouseEvent):void
		{
			mContainer.stopDrag();
		}
		
		private function onRightDown(e:MouseEvent):void
		{
			mContainer.startDrag();
		}
		
		private function onFileSelect(e:Event):void
		{
			if (isLoading == false)
			{
				if (mFile.extension == "jpg")
				{
					//通过jpg图片样板新建
					mLoader.unload();
					mLoader.load(new URLRequest(mFile.url));
					isLoading = true;
					removeBlocks();
				}
				else if (mFile.extension == "b")
				{
					//通过b文件恢复
					mFile.load();
				}
			}
			else
			{
				labName.text = "正在加载文件，请稍后再选择";
			}
		}
		
		private function onLoadImageComplete(e:Event):void
		{
			isLoading = false;
			
			//产生总宽高等于或大于样板图的方块矩阵
			var w:int = Tools.textures.w;
			var h:int = Tools.textures.h;
			var c:int = Math.ceil(mLoader.width / w);
			var r:int = Math.ceil(mLoader.height / h);
			
			var n:String = mFile.name.split('.')[0];
			var d:String = "file:///E:/qdisk/bawangdaluII/editor/source/map/";
			var vo:ProjectVO = new ProjectVO(n, r, c, w, h, d);
			mNewPanel.setParams(vo);
		
			labName.text = vo.name;
		}
		
		private function setTexture($index:int):void
		{
			if (mCurBlock)
			{
				mCurBlock.setTexture($index);
				labName.text = mCurProject.name;
			}
		}
		
		/**
		 * 点击方块执行的事件
		 * @param	$target 方块本身
		 */
		private function clickHandler($target:Block):void
		{
			mCurBlock.changeState(false);
			mCurBlock = $target;
			mCurBlock.changeState(true);
			
			if (chkFollow.selected)
			{
				mSelectView.x = mContainer.x + mBlockPanel.x + $target.x + 32;
				mSelectView.y = mContainer.y + mBlockPanel.y + $target.y + 32;
			}
		}
		
		/**
		 * 鼠标经过方块时执行的事件
		 * @param	$target
		 */
		private function overHandler($target:Block):void
		{
			if (isCover)
			{
				if ($target != mCurBlock)
				{
					$target.setTexture(mCurBlock.type);
				}
			}
		}
		
		private function handleRefer():void
		{
			//选择参考的样图
			mFile.browseForOpen("请选择参考样图", [new FileFilter("Image(jpg)", "*.jpg")]);
		}
		
		/**
		 * 新建工程
		 * @param	$param
		 */
		private function handleOk($vo:ProjectVO):void
		{
			mCurProject = $vo;
			createBlankMap();
		}
		
		/**
		 * 取消新建工程
		 */
		private function handleCancel():void
		{
			if (mBlockPanel.numChildren > 0)
			{
				App.stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
			}
			else
			{
				mBlockPanel.graphics.clear();
				mLoader.unload();
			}
		}
		
		/**
		 * 给空白地图填充纹理，创建纹理地图
		 * @param	$b 地图数据
		 */
		private function createMap($b:ByteArray):void
		{
			for (var i:int = 0; i < mBlockPanel.numChildren; i++)
			{
				var b:Block = mBlockPanel.getChildAt(i) as Block;
				b.setTexture($b.readByte());
			}
		}
		
		/**
		 * 创建空白地图
		 */
		private function createBlankMap(err:String = ""):void
		{
			labName.text = mCurProject.name + err;
			mRow = mCurProject.r;
			mColumn = mCurProject.c;
			var w:int = mCurProject.w;
			var h:int = mCurProject.h;
			
			//描大边
			with (mBlockPanel.graphics)
			{
				clear();
				lineStyle(1);
				moveTo(0, h * mRow);
				lineTo(0, 0);
				lineTo(w * mColumn, 0);
			}
			
			removeBlocks();
			
			//从对象池中获取对象并添加到mBlockPanel的显示列表上
			for (var i:int = 0; i < mRow; i++)
			{
				for (var j:int = 0; j < mColumn; j++)
				{
					var o:Object = {x: j * w, y: i * h, parent: mBlockPanel, click: clickHandler, over: overHandler};
					Tools.pools.take(Block, o);
				}
			}
			
			mCurBlock = mBlockPanel.getChildAt(0) as Block;
			mCurBlock.changeState(true);
			mContainer.y = 34;
			mSelectView.x = App.stage.stageWidth - mSelectView.width;
			mSelectView.y = App.stage.stageHeight - mSelectView.height;
			
			App.stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
		}
		
		private function removeBlocks():void
		{
			var b:Block;
			while (mBlockPanel.numChildren > 0)
			{
				//从尾开始删除显示对象，父容器不需要对未删除的子对象重新设置index值
				b = mBlockPanel.getChildAt(mBlockPanel.numChildren - 1) as Block;
				//归还对象到对象池，内置从父容器中移除的方法
				Tools.pools.giveBack(b, Block);
			}
		}
		
		private function onClick(e:MouseEvent):void
		{
			switch (e.target.name)
			{
				case "lnkNew": 
					//新建
					mNewPanel.popup();
					App.stage.removeEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
					break;
				case "lnkOpen": 
					mFile.browseForOpen("请选择地图源文件", [new FileFilter("Map(b)", "*.b")]);
					App.stage.removeEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
					break;
				case "lnkSave": 
					//保存数据文件
					save();
					break;
				default: 
			}
		}
		
		private function save():void
		{
			if (mCurProject)
			{
				//保存数据
				var n:String = mCurProject.name;
				var d:String = mCurProject.path;
				var nd:String = d + "/dfile/" + n + ".d";
				var nb:String = d + "/bfile/" + n + ".b";
				
				//生成数据 # 1-山 2-水 3-平原 4-森林 5-沙漠 ...
				var bd:ByteArray = new ByteArray;
				var bb:ByteArray = new ByteArray;
				
				bb.writeInt(mBlockPanel.x);
				bb.writeInt(mBlockPanel.y);
				bb.writeByte(mCurProject.r);
				bb.writeByte(mCurProject.c);
				bb.writeByte(mCurProject.w);
				bb.writeByte(mCurProject.h);
				
				for (var i:int = 0; i < mBlockPanel.numChildren; i++)
				{
					var b:Block = mBlockPanel.getChildAt(i) as Block;
					bd.writeByte(Tools.textures.getType(b.type));
					bb.writeByte(b.type);
				}
				
				//生成d文件
				var fd:File = new File(nd);
				mFileStream.open(fd, FileMode.WRITE);
				mFileStream.writeBytes(bd);
				mFileStream.close();
				
				//生成b文件
				var fb:File = new File(nb);
				mFileStream.open(fb, FileMode.WRITE);
				mFileStream.writeBytes(bb);
				mFileStream.close();
				
				labName.text = "已保存到" + d;
			}
			else
			{
				labName.text = "<font color='#FF0000'>未创建工程</font>";
			}
		}
		
		public function reSize():void
		{
			width = App.stage.stageWidth;
			height = App.stage.stageHeight;
			imgHead.width = App.stage.stageWidth;
		}
		
		/**总容器*/
		private var mContainer:Sprite;
		/**加载参考图片兼显示*/
		private var mLoader:Loader;
		/**文件类，用于选择图片路径或加载工程文件*/
		private var mFile:File;
		/**是否正在加载文件中*/
		private var isLoading:Boolean;
		/**装纹理块的容器*/
		private var mBlockPanel:Sprite;
		/**当前被选中的方块*/
		private var mCurBlock:Block;
		/**纹理选择框*/
		private var mSelectView:TextureSelectPanel;
		/**按数字键第一次记录值*/
		private var mFirstNumber:int;
		/**是否为第二次按数字键*/
		private var isSecond:Boolean = false;
		/**当前地图的行数*/
		private var mRow:int;
		/**当前地图的列数*/
		private var mColumn:int;
		/**是否在鼠标经过时用新的纹理覆盖*/
		private var isCover:Boolean;
		/**文件读写流*/
		private var mFileStream:FileStream;
		/**新建工程的面板*/
		private var mNewPanel:NewProject;
		/**当前工程的信息*/
		private var mCurProject:ProjectVO;
	}

}